#include "txt_read_ui.h"

#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include "esp_lvgl_port.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_heap_caps.h"
#include "file_iterator.h"
#include "jpeg_decoder.h"

#include "main_ui.h"
#include "md_images.h"
#include "md_languages.h"
#include "sd_card.h"

static const char *TAG = "txt_read_ui";

#define TEXT_FILE_PATH SD_MOUNT_POINT "/text" // 文本文件路径
#define READ_BUF_PATH  (128)                  //路径缓冲区大小
#define PAGE_TXT_SIZE  (128)                  //每页文本大小
/*
UTF-8 BOM: EF BB BF (3字节)

UTF-16 LE BOM: FF FE (2字节)

UTF-16 BE BOM: FE FF (2字节)
*/
#define tXT_HEADE_SIZE  (0)                  //每页文本大小
char page_tmp[PAGE_TXT_SIZE+1];
// 声明字体
LV_FONT_DECLARE(myFont);

// 全局变量
static lv_obj_t *text_label;
static lv_obj_t *page_label;
static lv_obj_t *title_label;
static uint32_t current_page = 0;
static uint32_t total_pages = 0;
static char *file_content = NULL;

void exit_txt_read_ui(lv_obj_t *root)
{

    // 释放文件内容内存
    if (file_content != NULL) {
        heap_caps_free(file_content);
        file_content = NULL;
    }

    switch_to_main_screen(); // 切换到主界面
    bsp_sdcard_unmount();    // 卸载SD卡

    /*删除对应的逻辑分析仪界面，防止多次调用，内存泄漏*/
    /*因为功能界面多,而且不常用,所以删除*/
    lv_obj_del(root); //也可以把lv_root_load_anim的auto_del设置为true
}

// 手势事件回调
static void event_handler(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);

    if (code == LV_EVENT_GESTURE) {
        lv_indev_t *indev = lv_indev_get_act();
        if (!indev)
            return;

        lv_dir_t dir = lv_indev_get_gesture_dir(indev);

        // 保留右划检测
        if (dir == LV_DIR_RIGHT) {
            exit_txt_read_ui(lv_event_get_current_target(e));
        }
    }
}

// 读取文本文件内容到缓冲区
static bool read_text_file_to_buffer(const char *file_path)
{
    FILE *file = fopen(file_path, "r");
    if (!file) {
        ESP_LOGE(TAG, "无法打开文件: %s", file_path);
        return false;
    }

    // 获取文件大小
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    // 分配足够的内存来存储文件内容
    file_content = heap_caps_malloc(file_size + 1 , MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
    if (!file_content) {
        ESP_LOGE(TAG, "内存分配失败");
        fclose(file);
        return false;
    }

    // 读取文件内容
    size_t read_size = fread(file_content, 1, file_size, file);
    file_content[read_size] = '\0';
    total_pages = read_size / PAGE_TXT_SIZE + (read_size % PAGE_TXT_SIZE?1:0);
    fclose(file);
    return true;
}

// 查找文本文件
static esp_err_t find_text_file(char *file_path_buf)
{
    DIR *dir = opendir(TEXT_FILE_PATH);
    if (!dir) {
        ESP_LOGE(TAG, "无法打开目录: %s", TEXT_FILE_PATH);
        return ESP_FAIL;
    }

    struct dirent *entry;
    esp_err_t ret = ESP_FAIL;

    while ((entry = readdir(dir)) != NULL) {
        // 跳过当前目录和上级目录
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
            continue;
        }

        // 检查文件扩展名
        char *ext = strrchr(entry->d_name, '.');
        if (ext && (strcasecmp(ext, ".txt") == 0 || strcasecmp(ext, ".text") == 0)) {
            snprintf(file_path_buf, READ_BUF_PATH, "%s/%s", TEXT_FILE_PATH, entry->d_name);
            ret = ESP_OK;
            break;
        }
    }

    closedir(dir);
    return ret;
}


// 显示当前页
static void show_current_page()
{
    if (current_page < total_pages && total_pages) {
        uint16_t index = current_page * PAGE_TXT_SIZE + tXT_HEADE_SIZE;
        //ESP_LOGI(TAG, "index : %d", index);
        if (current_page == total_pages-1)//最后一页
        {
            memcpy(page_tmp, file_content + index, total_pages % PAGE_TXT_SIZE? total_pages % PAGE_TXT_SIZE : PAGE_TXT_SIZE);
            page_tmp[total_pages % PAGE_TXT_SIZE] = '\0';
        }else{
            memcpy(page_tmp, file_content + index, PAGE_TXT_SIZE);
            page_tmp[PAGE_TXT_SIZE] = '\0';
        }
        lv_label_set_text(text_label, page_tmp);

        //ESP_LOGI(TAG, "page %d text : %s", current_page + 1, page_tmp);
        // 更新页码显示
        char page_info[20];
        snprintf(page_info, sizeof(page_info), "第 %d/%d 页", current_page + 1, total_pages);
        lv_label_set_text(page_label, page_info);

    } else {
        lv_label_set_text(text_label, "无内容可显示");
    }
}

// 下一页按钮回调
static void next_page_cb(lv_event_t *e)
{
    if (current_page < total_pages - 1) {
        current_page++;
        show_current_page();
    }
}

// 上一页按钮回调
static void prev_page_cb(lv_event_t *e)
{
    if (current_page > 0) {
        current_page--;
        show_current_page();
    }
}



/* 
 * @ brief:创建文本阅读UI
*/
lv_obj_t *create_txt_read_ui(void)
{
    // 创建根容器（全屏黑色背景）
    lv_obj_t *root = lv_obj_create(NULL);
    lv_obj_set_size(root, lv_pct(100), lv_pct(100));
    lv_obj_set_style_bg_color(root, lv_color_black(), LV_PART_MAIN);
    lv_obj_add_event_cb(root, event_handler, LV_EVENT_GESTURE, NULL);

    // 挂载SD卡
    esp_err_t ret = bsp_sdcard_mount();
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "SD card mount failed");
        // 创建错误提示界面
        lv_obj_t *label_err = lv_label_create(root);
        lv_label_set_text(label_err, "SD卡挂载失败");
        lv_obj_set_style_text_color(label_err, lv_color_white(), 0);
        lv_obj_set_style_text_font(label_err, &myFont, 0);
        lv_obj_align(label_err, LV_ALIGN_CENTER, 0, 0);
        return root;
    }

    // 设置背景颜色
    lv_obj_set_style_bg_color(root, lv_color_hex(0xFFFFFF), LV_PART_MAIN);

    // 创建标题
    title_label = lv_label_create(root);
    lv_obj_align(title_label, LV_ALIGN_TOP_MID, 0, 2);
    lv_obj_set_style_text_font(title_label, &myFont, LV_PART_MAIN);
    lv_obj_set_style_text_color(title_label, lv_color_hex(0x000000), LV_PART_MAIN);

    // 创建文本显示区域
    text_label = lv_label_create(root);
    lv_obj_set_size(text_label, lv_pct(95), lv_pct(75));
    lv_obj_align(text_label, LV_ALIGN_TOP_MID, 0, 30);
    lv_label_set_long_mode(text_label, LV_LABEL_LONG_WRAP);
    lv_obj_set_style_text_color(text_label, lv_color_hex(0x000000), LV_PART_MAIN);
    lv_obj_set_style_text_font(text_label, &myFont, LV_PART_MAIN);
    lv_obj_set_style_border_width(text_label, 1, LV_PART_MAIN);
    lv_obj_set_style_border_color(text_label, lv_color_hex(0xCCCCCC), LV_PART_MAIN);
    lv_obj_set_style_pad_all(text_label, 2, LV_PART_MAIN);

    // 创建页码显示
    page_label = lv_label_create(root);
    lv_obj_align(page_label, LV_ALIGN_BOTTOM_MID, 0, -5);
    lv_obj_set_style_text_color(page_label, lv_color_hex(0x666666), LV_PART_MAIN);
    lv_obj_set_style_text_font(page_label, &myFont, LV_PART_MAIN);

    // 创建上一页按钮
    lv_obj_t *prev_btn = lv_btn_create(root);
    lv_obj_set_size(prev_btn, 100, 30);
    lv_obj_align(prev_btn, LV_ALIGN_BOTTOM_LEFT, 5, -5);
    lv_obj_t *prev_label = lv_label_create(prev_btn);
    lv_label_set_text(prev_label, "上一页");
    lv_obj_center(prev_label);
    lv_obj_add_event_cb(prev_btn, prev_page_cb, LV_EVENT_CLICKED, NULL);

    // 创建下一页按钮
    lv_obj_t *next_btn = lv_btn_create(root);
    lv_obj_set_size(next_btn, 100, 30);
    lv_obj_align(next_btn, LV_ALIGN_BOTTOM_RIGHT, -5, -5);
    lv_obj_t *next_label = lv_label_create(next_btn);
    lv_label_set_text(next_label, "下一页");
    lv_obj_center(next_label);
    lv_obj_add_event_cb(next_btn, next_page_cb, LV_EVENT_CLICKED, NULL);

    /******************SD操作********************/
    char *read_buf = heap_caps_malloc(READ_BUF_PATH, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
    if (!read_buf) {
        ESP_LOGE(TAG, "内存分配失败");
        lv_label_set_text(title_label, "内存分配失败");
        return root;
    }

    // 从SD卡读取文本文件
    ret = find_text_file(read_buf);
    if (ESP_OK != ret) {
        lv_label_set_text(title_label, "未找到文本文件");
        lv_label_set_text(text_label, "请在SD卡/text目录下放置.txt文件");
        heap_caps_free(read_buf);
        return root;
    }

    // 显示文件名
    char *file_name = strrchr(read_buf, '/'); //获取文件名
    if (file_name)
        file_name++;
    else
        file_name = read_buf;

    lv_label_set_text(title_label, file_name);
    ESP_LOGI(TAG, "text file name: %s", file_name);

    // 读取文件内容到缓冲区
    if (!read_text_file_to_buffer(read_buf)) {
        lv_label_set_text(text_label, "读取文件失败");
        heap_caps_free(read_buf);
        return root;
    }

    heap_caps_free(read_buf); // 释放路径缓冲区
    lv_obj_update_layout(root);
    // 修正日志输出，只打印文件内容的前100个字符以避免日志过长
  // ESP_LOGI(TAG, "text file content: %.100s", file_content);

    current_page = 0;
    show_current_page();

    return root;
}